package com.katesoft.scale4j.rttp.messaging.lock;

import org.springframework.integration.Message;
import org.springframework.integration.MessageHeaders;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.integration.transformer.AbstractTransformer;

/**
 * This class is more enricher rather than message transformer. Dedicated message header needs to be
 * created for message and later can be used for distributed locking. This is needed for concurrent
 * processing restriction of the same message(logically same).
 * 
 * 'lockId' - name for lock message header.
 * 
 * @author kate2007
 * 
 */
public abstract class AbstractInboundLockHeaderEnricher extends AbstractTransformer {
   public static final String LOCK_ID_HEADER = "lockId";

   @Override
   protected Object doTransform(Message<?> message) throws Exception {
      Message<?> newMessage = message;
      MessageHeaders headers = message.getHeaders();
      String lockId = deriveLockId(message);

      if (headers.get(LOCK_ID_HEADER) == null) {
         logger.debug(String.format("adding lockId header=%s to existing headers=%s", lockId,
                  headers));
         newMessage = MessageBuilder.withPayload(message.getPayload()).copyHeaders(headers)
                  .setHeaderIfAbsent(LOCK_ID_HEADER, lockId).build();
      }

      return newMessage;
   }

   /**
    * derive lock id for given message. For the same messages (logically the same messages) lockId
    * must not change and remains the same.
    * 
    * For file lockId can be full file path. For jms message it can be JMS messageId. It is up to
    * user to determine logical lockId.
    * 
    * 
    * @param message
    *           original message
    * @return lock id identifier of the message
    */
   protected abstract String deriveLockId(Message<?> message);
}
